home *** CD-ROM | disk | FTP | other *** search
- /* lineout.c -
- Implements line-oriented output format.
-
- Written by James Clark (jjc@jclark.com).
- */
-
- #include "config.h"
- #include "std.h"
- #include "entity.h" /* Templates for entity control blocks. */
- #include "adl.h" /* Definitions for attribute list processing. */
- #include "sgmlmain.h" /* Main interface to SGML services. */
- #include "lineout.h"
- #include "appl.h"
-
- static VOID flush_data P((void));
- static VOID define_external_entity P((PNE));
- static VOID define_entity P((UNCH *));
- static VOID handle_attributes P((UNCH *, struct ad *));
- static VOID handle_token_list P((UNCH *, struct ad *, int));
- static VOID handle_single_token P((UNCH *, struct ad *, int));
- static VOID output_notation P((UNCH *, UNCH *, UNCH *));
- static VOID output_internal_entity P((UNCH *, int, UNCH *));
- static VOID output_external_entity P((UNCH *, int, UNIV, UNCH *, UNCH *,
- UNCH *));
- static VOID output_subdoc P((UNCH *, UNIV, UNCH *, UNCH *));
- #ifdef SUPPORT_SUBDOC
- static VOID process_subdoc P((UNCH *, UNIV));
- #endif /* SUPPORT_SUBDOC */
- static VOID output_record_end P((void));
- static VOID output_pcdata P((UNS, UNCH *));
- static VOID output_cdata P((UNS, UNCH *));
- static VOID output_sdata P((UNS, UNCH *));
- static VOID output_entity_reference P((UNCH *));
- static VOID output_start_tag P((UNCH *));
- static VOID output_end_tag P((UNCH *));
- static VOID output_processing_instruction P((UNS, UNCH *));
- static VOID output_implied_attribute P((UNCH *, UNCH *));
- static char *attribute_type_string P((int));
- static VOID output_begin_attribute P((UNCH *, UNCH *, int));
- static VOID output_attribute_token P((UNS, UNCH *));
- static VOID output_end_attribute P((void));
- static VOID print_data P((UNS, UNCH *, int));
- static VOID print_string P((UNS, UNCH *, int));
- static VOID print_id P((UNIV, UNCH *, UNCH *));
- static VOID print_filename P((char *));
- static VOID output_location P((void));
- static VOID output_appinfo P((UNS, UNCH *));
-
- static int have_data = 0;
- static char *current_filename = 0;
- static unsigned long current_lineno = 0;
-
- VOID process_document(subdocsw)
- int subdocsw;
- {
- enum sgmlevent rc;
- struct rcbtag rcbtag;
- struct rcbdata rcbdaf;
-
- while ((rc = sgmlnext(&rcbdaf, &rcbtag)) != SGMLEOD) {
- #ifdef SUPPORT_SUBDOC
- if (rc == SGMLDAF && !CONTERSW(rcbdaf) && NDESW(rcbdaf)
- && NEXTYPE(NEPTR(rcbdaf)) == ESNSUB) {
- if (!suppsw && !sgmlment(NEENAME(NEPTR(rcbdaf))))
- define_external_entity(NEPTR(rcbdaf));
- process_subdoc(NEENAME(NEPTR(rcbdaf)) + 1,
- NEID(NEPTR(rcbdaf)));
- continue;
- }
- #endif /* SUPPORT_SUBDOC */
- if (!suppsw)
- switch (rc) {
- case SGMLDAF:
- if (CONTERSW(rcbdaf))
- break;
- if (CDESW(rcbdaf))
- output_cdata(CDATALEN(rcbdaf), CDATA(rcbdaf));
- else if (SDESW(rcbdaf))
- output_sdata(CDATALEN(rcbdaf), CDATA(rcbdaf));
- else if (NDESW(rcbdaf)) {
- assert(NEXTYPE(NEPTR(rcbdaf)) != ESNSUB);
- if (!sgmlment(NEENAME(NEPTR(rcbdaf))))
- define_external_entity(NEPTR(rcbdaf));
- output_entity_reference(NEENAME(NEPTR(rcbdaf)) + 1);
- }
- else
- output_pcdata(CDATALEN(rcbdaf), CDATA(rcbdaf));
- break;
- case SGMLSTG:
- if (CONTERSW(rcbtag))
- break;
- if (ALPTR(rcbtag))
- handle_attributes((UNCH *)NULL, ALPTR(rcbtag));
- output_start_tag(CURGI(rcbtag));
- break;
- case SGMLETG:
- if (CONTERSW(rcbtag))
- break;
- output_end_tag(CURGI(rcbtag));
- break;
- case SGMLPIS:
- if (CONTERSW(rcbdaf))
- break;
- output_processing_instruction(PDATALEN(rcbdaf),
- PDATA(rcbdaf));
- break;
- case SGMLREF:
- if (CONTERSW(rcbdaf))
- break;
- output_record_end();
- break;
- case SGMLAPP:
- if (CONTERSW(rcbdaf))
- break;
- if (!subdocsw)
- output_appinfo(ADATALEN(rcbdaf), ADATA(rcbdaf));
- break;
- default:
- abort();
- }
- }
- }
-
- /* Output an indication that the document was conforming. */
-
- VOID output_conforming()
- {
- if (!suppsw)
- printf("%c\n", CONFORMING_CODE);
- }
-
- static VOID define_external_entity(p)
- PNE p;
- {
- if (NEXTYPE(p) == ESNSUB)
- output_subdoc(NEENAME(p) + 1, NEID(p), NEPUBID(p), NESYSID(p));
- else {
- if (!NEDCNMARK(p))
- output_notation(NEDCN(p) + 1, NEDCNPUBID(p), NEDCNSYSID(p));
- output_external_entity(NEENAME(p) + 1, NEXTYPE(p), NEID(p),
- NEPUBID(p), NESYSID(p), NEDCN(p) + 1);
- if (NEAL(p))
- handle_attributes(NEENAME(p) + 1, NEAL(p));
- }
- }
-
- static VOID define_entity(ename)
- UNCH *ename;
- {
- int rc;
- PNE np;
- UNCH *tp;
-
- if (sgmlment(ename)) /* already defined it */
- return;
- rc = sgmlgent(ename, &np, &tp);
- switch (rc) {
- case 1:
- define_external_entity(np);
- break;
- case 2:
- case 3:
- output_internal_entity(ename + 1, rc == 3, tp);
- break;
- }
- }
-
- /* ENT is the name of the entity with which these attributes are associated;
- if it's NULL, they're associated with the next start tag. */
-
- static VOID handle_attributes(ent, al)
- UNCH *ent;
- struct ad *al;
- {
- int aln;
-
- for (aln = 1; aln <= ADN(al); aln++) {
- if (GET(ADFLAGS(al, aln), AERROR))
- ;
- else if (GET(ADFLAGS(al, aln), AINVALID))
- ;
- else if (ADVAL(al, aln) == NULL)
- output_implied_attribute(ent, ADNAME(al, aln));
- else if (ADTYPE(al, aln) >= ATKNLIST)
- handle_token_list(ent, al, aln);
- else
- handle_single_token(ent, al, aln);
- if (BITON(ADFLAGS(al, aln), AGROUP))
- aln += ADNUM(al, aln);
- }
- }
-
- static VOID handle_token_list(ent, al, aln)
- UNCH *ent;
- struct ad *al;
- int aln;
- {
- UNCH *ptr;
- int i;
- if (ADTYPE(al, aln) == AENTITYS) {
- ptr = ADVAL(al, aln);
- for (i = 0; i < ADNUM(al, aln); i++) {
- /* Temporarily make token look like normal
- name with length and EOS. */
- UNCH c = ptr[*ptr + 1];
- ptr[*ptr + 1] = '\0';
- *ptr += 2;
- define_entity(ptr);
- *ptr -= 2;
- ptr += *ptr + 1;
- *ptr = c;
- }
- }
- output_begin_attribute(ent, ADNAME(al, aln), ADTYPE(al, aln));
- ptr = ADVAL(al, aln);
- for (i = 0; i < ADNUM(al, aln); i++) {
- /* The first byte is a length NOT including the length
- byte; the tokens are not EOS terminated. */
- output_attribute_token(*ptr, ptr + 1);
- ptr += *ptr + 1;
- }
- output_end_attribute();
- }
-
- static VOID handle_single_token(ent, al, aln)
- UNCH *ent;
- struct ad *al;
- int aln;
- {
- if (ADTYPE(al, aln) == ANOTEGRP && !DCNMARK(ADDATA(al, aln).x))
- output_notation(ADVAL(al, aln) + 1,
- ADDATA(al, aln).x->pubid,
- ADDATA(al, aln).x->sysid);
- else if (ADTYPE(al, aln) == AENTITY)
- define_entity(ADVAL(al, aln));
- output_begin_attribute(ent, ADNAME(al, aln), ADTYPE(al, aln));
- if (ADTYPE(al, aln) == ACHARS)
- output_attribute_token(ustrlen(ADVAL(al, aln)), ADVAL(al, aln));
- else
- output_attribute_token(*ADVAL(al, aln) - 2, ADVAL(al, aln) + 1);
- output_end_attribute();
- }
-
- static VOID output_notation(name, pubid, sysid)
- UNCH *name;
- UNCH *pubid, *sysid;
- {
- flush_data();
- print_id((UNIV)0, pubid, sysid);
- printf("%c%s\n", DEFINE_NOTATION_CODE, name);
- }
-
- static VOID output_internal_entity(ename, is_sdata, text)
- UNCH *ename;
- int is_sdata;
- UNCH *text;
- {
- flush_data();
- printf("%c%s %s ", DEFINE_INTERNAL_ENTITY_CODE, ename,
- is_sdata ? "SDATA" : "CDATA");
- print_string(text ? ustrlen(text) : 0, text, 0);
- putchar('\n');
- }
-
- static VOID output_subdoc(nm, id, pubid, sysid)
- UNCH *nm;
- UNIV id;
- UNCH *pubid, *sysid;
- {
- flush_data();
- print_id(id, pubid, sysid);
- printf("%c%s\n", DEFINE_SUBDOC_ENTITY_CODE, nm);
- }
-
- #ifdef SUPPORT_SUBDOC
-
- static VOID process_subdoc(nm, id)
- UNCH *nm;
- UNIV id;
- {
- if (!suppsw) {
- flush_data();
- output_location();
- printf("%c%s\n", START_SUBDOC_CODE, nm);
- fflush(stdout);
- }
- fflush(stderr);
-
- if (id) {
- char **argv;
- int ret;
-
- argv = make_argv(id);
- ret = run_process(argv);
- if (ret != 0)
- suberr++;
-
- current_filename = 0;
- free(argv);
- if (ret == 0)
- get_subcaps();
- }
- else {
- suberr++;
- appl_error(E_SUBDOC, nm);
- }
-
- if (!suppsw)
- printf("%c%s\n", END_SUBDOC_CODE, nm);
- }
-
- #endif /* SUPPORT_SUBDOC */
-
- static VOID output_external_entity(nm, xtype, id, pubid, sysid, dcn)
- UNCH *nm, *dcn;
- UNIV id;
- UNCH *pubid, *sysid;
- int xtype;
- {
- char *type;
-
- flush_data();
-
- print_id(id, pubid, sysid);
-
- switch (xtype) {
- case ESNCDATA:
- type = "CDATA";
- break;
- case ESNNDATA:
- type = "NDATA";
- break;
- case ESNSDATA:
- type = "SDATA";
- break;
- default:
- return;
- }
- printf("%c%s %s %s\n", DEFINE_EXTERNAL_ENTITY_CODE, nm, type, dcn);
- }
-
- static VOID output_record_end()
- {
- static UNCH re = RECHAR;
- print_data(1, &re, 0);
- }
-
- static VOID output_pcdata(n, s)
- UNS n;
- UNCH *s;
- {
- print_data(n, s, 0);
- }
-
- static VOID output_cdata(n, s)
- UNS n;
- UNCH *s;
- {
- print_data(n, s, 0);
- }
-
- static VOID output_sdata(n, s)
- UNS n;
- UNCH *s;
- {
- print_data(n, s, 1);
- }
-
- static VOID output_entity_reference(s)
- UNCH *s;
- {
- flush_data();
- output_location();
- printf("%c%s\n", REFERENCE_ENTITY_CODE, s);
- }
-
- static VOID output_start_tag(s)
- UNCH *s;
- {
- flush_data();
- output_location();
- printf("%c%s\n", START_CODE, s);
- }
-
- static VOID output_end_tag(s)
- UNCH *s;
- {
- flush_data();
- printf("%c%s\n", END_CODE, s);
- }
-
- static VOID output_processing_instruction(n, s)
- UNS n;
- UNCH *s;
- {
- flush_data();
- output_location();
- putchar(PI_CODE);
- print_string(n, s, 0);
- putchar('\n');
- }
-
- static VOID output_appinfo(n, s)
- UNS n;
- UNCH *s;
- {
- flush_data();
- output_location();
- putchar(APPINFO_CODE);
- print_string(n, s, 0);
- putchar('\n');
- }
-
-
- static VOID output_implied_attribute(ent, aname)
- UNCH *ent, *aname;
- {
- flush_data();
- if (ent)
- printf("%c%s %s IMPLIED\n", DATA_ATTRIBUTE_CODE, ent, aname);
- else
- printf("%c%s IMPLIED\n", ATTRIBUTE_CODE, aname);
- }
-
- static char *attribute_type_string(type)
- int type;
- {
- switch (type) {
- case ANMTGRP:
- case ANAME:
- case ANMTOKE:
- case ANUTOKE:
- case ANUMBER:
- case ANAMES:
- case ANMTOKES:
- case ANUTOKES:
- case ANUMBERS:
- case AID:
- case AIDREF:
- case AIDREFS:
- return "TOKEN";
- case ANOTEGRP:
- return "NOTATION";
- case ACHARS:
- return "CDATA";
- case AENTITY:
- case AENTITYS:
- return "ENTITY";
- }
- #if 0
- fatal("invalid attribute type %d", type);
- #endif
- return "INVALID";
- }
-
- static VOID output_begin_attribute(ent, aname, type)
- UNCH *ent, *aname;
- int type;
- {
- flush_data();
- if (ent)
- printf("%c%s %s %s", DATA_ATTRIBUTE_CODE, ent, aname,
- attribute_type_string(type));
- else
- printf("%c%s %s", ATTRIBUTE_CODE, aname,
- attribute_type_string(type));
-
- }
-
- static VOID output_attribute_token(vallen, val)
- UNS vallen;
- UNCH *val;
- {
- putchar(' ');
- print_string(vallen, val, 0);
- }
-
- static VOID output_end_attribute()
- {
- putchar('\n');
- }
-
- static VOID print_data(n, s, is_sdata)
- UNS n;
- UNCH *s;
- int is_sdata;
- {
- if (n > 0 || is_sdata) {
- if (n == 1 && *s == RECHAR)
- current_lineno++;
- else
- output_location();
- if (!have_data)
- putchar(DATA_CODE);
- print_string(n, s, is_sdata);
- have_data = 1;
- }
- }
-
- static VOID flush_data()
- {
- if (have_data) {
- putchar('\n');
- have_data = 0;
- }
- }
-
- static VOID output_location()
- {
- char *filename;
- unsigned long lineno;
- int filename_changed = 0;
-
- if (!locsw)
- return;
- if (!sgmlloc(&lineno, &filename))
- return;
- if (!current_filename || strcmp(filename, current_filename) != 0)
- filename_changed = 1;
- else if (lineno == current_lineno)
- return;
- flush_data();
- printf("%c%lu", LOCATION_CODE, lineno);
- current_lineno = lineno;
- if (filename_changed) {
- putchar(' ');
- print_filename(filename);
- current_filename = filename;
- }
- putchar('\n');
- }
-
- static VOID print_string(slen, s, is_sdata)
- UNS slen;
- UNCH *s;
- int is_sdata;
- {
- if (is_sdata)
- fputs("\\|", stdout);
- while (slen > 0) {
- UNCH ch = *s++;
- slen--;
- if (ch == DELSDATA) {
- if (is_sdata)
- ; /* I don't think this should happen */
- else
- fputs("\\|", stdout);
- ;
- }
- else if (ch == DELCDATA)
- ;
- else {
- if (ch == DELNONCH) {
- if (!slen)
- break;
- ch = UNSHIFTNON(*s);
- s++;
- slen--;
- }
- switch (ch) {
- case RECHAR:
- fputs("\\n", stdout);
- break;
- case '\\':
- fputs("\\\\", stdout);
- break;
- default:
- if (ISASCII(ch) && isprint(ch))
- putchar(ch);
- else
- printf("\\%03o", ch);
- break;
- }
- }
- }
- if (is_sdata)
- fputs("\\|", stdout);
- }
-
-
- static VOID print_id(id, pubid, sysid)
- UNIV id;
- UNCH *pubid;
- UNCH *sysid;
- {
-
- if (pubid) {
- putchar(PUBID_CODE);
- print_string(ustrlen(pubid), pubid, 0);
- putchar('\n');
- }
-
- if (sysid) {
- putchar(SYSID_CODE);
- print_string(ustrlen(sysid), sysid, 0);
- putchar('\n');
- }
-
- if (id) {
- char *p;
-
- for (p = id; *p != '\0'; p++) {
- putchar(FILE_CODE);
- do {
- switch (*p) {
- case '\\':
- fputs("\\\\", stdout);
- break;
- case '\n':
- fputs("\\n", stdout);
- break;
- default:
- if (ISASCII(*p) && isprint((UNCH)*p))
- putchar(*p);
- else
- printf("\\%03o", (UNCH)*p);
- break;
- }
- } while (*++p);
- putchar('\n');
- }
- }
- }
-
- static VOID print_filename(s)
- char *s;
- {
- for (; *s; s++)
- switch (*s) {
- case '\\':
- fputs("\\\\", stdout);
- break;
- case '\n':
- fputs("\\n", stdout);
- break;
- default:
- if (ISASCII(*s) && isprint((UNCH)*s))
- putchar(*s);
- else
- printf("\\%03o", (UNCH)*s);
- break;
- }
- }
-
- /*
- Local Variables:
- c-indent-level: 5
- c-continued-statement-offset: 5
- c-brace-offset: -5
- c-argdecl-indent: 0
- c-label-offset: -5
- End:
- */
-